#ifndef _SM2_H
#define _SM2_H

#include "sm2_ec.h"
#include "sm2_operation.h"
#include "sm3.h"
#include <stdlib.h>
#include <stdint.h>

typedef struct {
    sm2_uint256_t private_key;
    SM2_Point public_key;
}SM2_Key;

// int sm2_key_generate(SM2_Key *key);
// int sm2_set_private_key(SM2_Key *key, sm2_uint256_t private_key);
// int sm2_set_public_key(SM2_Key *key, sm2_uint256_t public_key);
// void sm2_print_key(SM2_Key *key);

void print_bytes(const uint8_t *s, size_t n);

typedef struct {
	uint8_t r[32];
	uint8_t s[32];
} SM2_Signature;

void sm2_signature_generate(const SM2_Key *key, const uint8_t Z_A[32], const uint8_t* message, size_t message_size, SM2_Signature *sig);
int sm2_signature_verify(SM2_Point *public_key, const uint8_t Z_A[32], const uint8_t* message, size_t message_size, SM2_Signature *sig);
void sm2_rand(sm2_uint256_t k, const sm2_uint256_t low, const sm2_uint256_t high);
void sm2_compute_z(uint8_t Z_A[32], const SM2_Point *pub, const uint8_t *id, unsigned short n_bytes);
// int sm2_sign(const SM2_Key *key, const uint8_t Z_A[32], const char* message, size_t message_size, SM2_Signature *sig);
// int sm2_verify();

// typedef struct {
// 	sm2_z256_t k;
// 	sm2_z256_t x1_modn;
// } SM2_SIGN_PRE_COMP;

// #define SM2_SIGN_PRE_COMP_COUNT 32


#define SM2_MIN_SIGNATURE_SIZE 8
#define SM2_MAX_SIGNATURE_SIZE 72
// int sm2_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen);
// int sm2_sign(const SM2_Key *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen);
// int sm2_verify(const SM2_Key *key, const uint8_t dgst[32], const uint8_t *sig, size_t siglen);

// enum {
// 	SM2_signature_compact_size = 70,
// 	SM2_signature_typical_size = 71,
// 	SM2_signature_max_size = 72,
// };
// int sm2_sign_fixlen(const SM2_Key *key, const uint8_t dgst[32], size_t siglen, uint8_t *sig);



#define SM2_DEFAULT_ID		"1234567812345678"
#define SM2_DEFAULT_ID_LENGTH	(sizeof(SM2_DEFAULT_ID) - 1)  // LENGTH for string and SIZE for bytes
#define SM2_DEFAULT_ID_BITS	(SM2_DEFAULT_ID_LENGTH * 8)
#define SM2_MAX_ID_BITS		65535
#define SM2_MAX_ID_LENGTH	(SM2_MAX_ID_BITS/8)





// typedef struct {
// 	SM3_CTX sm3_ctx;
// 	SM3_CTX saved_sm3_ctx;
// 	SM2_Key key;
// 	sm2_z256_t fast_sign_private;
// 	SM2_SIGN_PRE_COMP pre_comp[SM2_SIGN_PRE_COMP_COUNT];
// 	unsigned int num_pre_comp;

// 	// verify public point table, P, 2P, ..., 16P
// 	SM2_Z256_POINT public_point_table[16];
// } SM2_SIGN_CTX;

// int sm2_sign_init(SM2_SIGN_CTX *ctx, const SM2_Key *key, const char *id, size_t idlen);
// int sm2_sign_update(SM2_SIGN_CTX *ctx, const uint8_t *data, size_t datalen);
// int sm2_sign_finish(SM2_SIGN_CTX *ctx, uint8_t *sig, size_t *siglen);
// int sm2_sign_reset(SM2_SIGN_CTX *ctx);
// int sm2_sign_finish_fixlen(SM2_SIGN_CTX *ctx, size_t siglen, uint8_t *sig);

// typedef struct {
// 	SM3_CTX sm3_ctx;
// 	SM3_CTX saved_sm3_ctx;
// 	SM2_Key key;
// 	SM2_Z256_POINT public_point_table[16];
// } SM2_VERIFY_CTX;

// int sm2_verify_init(SM2_VERIFY_CTX *ctx, const SM2_Key *key, const char *id, size_t idlen);
// int sm2_verify_update(SM2_VERIFY_CTX *ctx, const uint8_t *data, size_t datalen);
// int sm2_verify_finish(SM2_VERIFY_CTX *ctx, const uint8_t *sig, size_t siglen);
// int sm2_verify_reset(SM2_VERIFY_CTX *ctx);

/* Functionalities */
// void sm2_generate_keypair();            // SM2生成密钥对
// void sm2_generate_pubkey();             // SM2生成公钥
// void sm2_generate_privatekey();         // SM2生成私钥
// void sm2_sign();                        // SM2签名
// void sm2_verify();                      // SM2验签
// void ec_parameter_verification();      // 椭圆曲线参数验证

#endif